
#include <stdio.h>
#include <stdlib.h>

/**

Esta seria nuestra clase nodo en java
dato = nuestro dato entero.
procesado = nuestro marcador de procesado -1 = false, 1 = true.
frecuencia = las veces que aparece este numero en el archivo.
*/
typedef struct nodo {
    int dato;
    int procesado;
    long frecuencia;
    struct nodo *siguiente;
} Elemento;

/**

Nuestra clase lista en java
*/
typedef struct listaFrecuencias {
    Elemento *inicio;
    Elemento *fin;
    int tam;
} Lista;

/**
Nuestro constructor en la clase lista
*/
void iniciaLista(Lista *lista) {
    lista->inicio = NULL;
    lista->fin = NULL;
    lista->tam = 0;
}

/**
Nuestro metodo actualiza lista... si la lista esta vacia, inserta un elemento 
al principio de la lista. si la lista tiene al menos un elemento, llama al metodo
que insert un elemento al final de la lista.
**/
int inserta(Lista * lista, int datoRecibido) {

if(lista->tam == 0 ){
    Elemento *nuevo_elemento;

    if ((nuevo_elemento = (Elemento *) malloc(sizeof (Elemento))) == NULL)
        return -1;
   
    nuevo_elemento->dato = datoRecibido;

    nuevo_elemento->siguiente = NULL;
    lista->inicio = nuevo_elemento;
    lista->fin = nuevo_elemento;
    lista->tam++;
    return 0;
}else{
    insertaFinLista(lista,datoRecibido);
}

}

/**
recorremos la lista e insertamos al final de la lista.
*/
int insertaFinLista (Lista * lista, int datoRecibido){
  Elemento *nuevo_elemento;
  if ((nuevo_elemento = (Elemento *) malloc (sizeof (Elemento))) == NULL)
    return -1;
 
    nuevo_elemento->dato = datoRecibido;
  lista->fin->siguiente = nuevo_elemento;
  
  //actual->siguiente = nuevo_elemento;
  nuevo_elemento->siguiente = NULL;

  lista->fin = nuevo_elemento;

  lista->tam++;
  return 0;
}

/**
muestra, la direccion de memoria de los elementos, su dato, y frecuencias.
*/
void verLista (Lista * lista){
  Elemento *actual;
  actual = lista->inicio;
  while (actual != NULL){
      printf ("%p - %c - %d\n", actual,(char)actual->dato,actual->frecuencia);
      actual = actual->siguiente;
  }
}

/**
elimina nuestra lista, llamando recursivamente al metodo elimina inicio.
*/
void eliminarLista(Lista * lista){
  while (lista->tam > 0)
    eliminaInicio (lista);
}

/**
elimina un elemento (inicio) de nuestra lista.
si hay solo un elemento libera memoria de ambos punteros (inicio,fin)
*/
int eliminaInicio (Lista * lista){
  if (lista->tam == 0)
    return -1;
  Elemento *sup_elemento;
  sup_elemento = lista->inicio;
  lista->inicio = lista->inicio->siguiente;
  if (lista->tam == 1)
    lista->fin = NULL;
  free (sup_elemento);
  lista->tam--;
  return 0;
}



/**
prueba de la lista....
*/

int main(int argc, char** argv) {
  char *nom;    
  Lista *lista;
  Elemento *actual;

  if ((lista = (Lista *) malloc (sizeof (Lista))) == NULL)
    return -1;
  if ((nom = (char *) malloc (50)) == NULL)
    return -1;
  actual = NULL;



iniciaLista(lista);
inserta(lista,'f');
inserta(lista,2);
inserta(lista,3);
inserta(lista,4);
inserta(lista,5);
verLista(lista);
printf("\n==========\n");

inserta(lista,1);
inserta(lista,2);
inserta(lista,3);
inserta(lista,4);
inserta(lista,5);
verLista(lista);
printf("\n==========\n");
inserta(lista,1);
inserta(lista,2);
inserta(lista,3);
inserta(lista,4);
inserta(lista,5);
verLista(lista);
printf("\n==========\n");


eliminarLista(lista);

verLista(lista);
printf("\n==========\n");

    return (EXIT_SUCCESS);
}
